﻿using System;
using System.Collections.Generic;
using System.Text;

using WinHttp;
using System.IO;
using ServerHelper;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Collections;
using System.Windows.Navigation;

namespace HomeMediaBrowser
{
    public enum TaskType
    {
        TASK_ROOT,          //All Root Library
        TASK_LIBRARY,       //One Library
        TASK_MEDIAS,        //One Folder Contain Medias
        TASK_MEDIA,         //One Media
        TASK_MEDIATHUMB,    //One Media Thumb
        TASK_LOGIN,         //Login to google service.
        TASK_ADDSERVERFOLDER,
        TASK_REMOVESERVERFOLDER,
        TASK_SERVERSTATUS,
        TASK_DOWNLOADOPEN,
    };
    public class DownloadHelper
    {
        public DownloadHelper(MainPanel Main, TaskType Taskt, string Path)
        {
            Logic = Main;
            Param = Path;
            //ServerIP = "http://192.168.1.190:8080/";
            ServerIP = Main.ServerIP;
            Task = Taskt;
            try
            {
                WinHttpClass = new WinHttpRequestClass();
                WinHttpClass.OnResponseFinished += new IWinHttpRequestEvents_OnResponseFinishedEventHandler(WinHttpClass_OnResponseFinished);
                WinHttpClass.OnError += new IWinHttpRequestEvents_OnErrorEventHandler(WinHttpClass_OnError);
                
                switch (Taskt)
                {
                    case TaskType.TASK_ROOT:
                        {
                            WinHttpClass.SetTimeouts(10000, 10000, 10000, -1);
                            string Ip = ServerIP + "Root";
                            Ip = Microsoft.JScript.GlobalObject.encodeURI(Ip);
                            WinHttpClass.Open("Get", Ip, false);
                            WinHttpClass.Send(null);
                            
                    //        bool bresponse = WinHttpClass.WaitForResponse(10000);

                        }
                        break;
                    case TaskType.TASK_MEDIAS:
                        {
                            string Ip = ServerIP + "Content?path=" + Path;
                            Ip = Microsoft.JScript.GlobalObject.encodeURI(Ip);
                            WinHttpClass.Open("Get", Ip, true);
                            WinHttpClass.Send(null);
                        }
                        break;
                    case TaskType.TASK_DOWNLOADOPEN:
                    case TaskType.TASK_MEDIA:
                        {
                            string Ip = ServerIP + "Download?path=" + Path;
                            Ip = Microsoft.JScript.GlobalObject.encodeURI(Ip);
                            WinHttpClass.OnResponseDataAvailable += new IWinHttpRequestEvents_OnResponseDataAvailableEventHandler(WinHttpClass_DownloadPercent);
                            WinHttpClass.Open("Get", Ip, true);

                            DownloadFile = new FileStream(Logic.GetCachePath(Param), FileMode.Create);
                            DownloadLen = 0;
                            WinHttpClass.Send(null);
                        }
                        break;
                    case TaskType.TASK_MEDIATHUMB:
                        {
                            string Ip = ServerIP + "Thumbnail?path=" + Path;
                            Ip = Microsoft.JScript.GlobalObject.encodeURI(Ip);
                            WinHttpClass.Open("Get", Ip, true);
                            WinHttpClass.Send(null);
                        }
                        break;
                    case TaskType.TASK_ADDSERVERFOLDER:
                        {
                            string Ip = ServerIP + "server/addfolder?folder=" + Path;
                            Ip = Microsoft.JScript.GlobalObject.encodeURI(Ip);
                            WinHttpClass.Open("Get", Ip, true);
                            WinHttpClass.Send(null);
                        }
                        break;
                    case TaskType.TASK_REMOVESERVERFOLDER:
                        {
                            string Ip = ServerIP + "server/removefolder?folder=" + Path ;
                            Ip = Microsoft.JScript.GlobalObject.encodeURI(Ip);
                            WinHttpClass.Open("Get", Ip, true);
                            WinHttpClass.Send(null);
                        }
                        break;
                    case TaskType.TASK_SERVERSTATUS:
                        {
                            string Ip = ServerIP + "server/status";
                            Ip = Microsoft.JScript.GlobalObject.encodeURI(Ip);
                            WinHttpClass.Open("Get", Ip, true);
                            WinHttpClass.Send(null);
                        }
                        break;
                    //case TaskType.TASK_LOGIN:
                    //    {
                    //        //1. Login
                    //        //    URL: http://127.0.0.1/server/login?username=xxxxxx&passwd=xxxxxxx
                    //        //    Response Format:
                    //        //    <LoginResponse Status="OK/ERROR" Reason=“xxxxxxxxx"/>
                    //        //    OK表示Login成功，ERROR表示失败。
                    //        //    Reason是失败原因。

                    //        string Ip = ServerIP + "login?" + Path; // username=xxxxxx&passwd=xxxxxxx
                    //        Ip = Microsoft.JScript.GlobalObject.encodeURI(Ip);
                    //        WinHttpClass.Open("Get", Ip, true);
                    //        WinHttpClass.Send(null);
                    //    }
                    //    break;
                }
            }
            catch (Exception e)
            {

                MessageBox.Show(e.Message);
                Console.WriteLine(e.Message);
            }
        }

        public void WinHttpClass_OnResponseFinished()
        {
            switch (Task)
            {
                case TaskType.TASK_ROOT:
                    WinHttpClass_OnRoot();
                    break;
                case TaskType.TASK_MEDIA:
                    WinHttpClass_OnMedia();
                    break;
                case TaskType.TASK_MEDIAS:
                    WinHttpClass_OnMedias();
                    break;
                case TaskType.TASK_MEDIATHUMB:
                    WinHttpClass_OnMediaThumb();
                    break;
                case TaskType.TASK_LOGIN:
                    WinHttpClass_OnLogin();
                    break;
                case TaskType.TASK_ADDSERVERFOLDER:
                case TaskType.TASK_REMOVESERVERFOLDER:
                    DownloadHelper MediaHelper = new DownloadHelper(Logic, TaskType.TASK_ROOT,"");
                    break;
                case TaskType.TASK_SERVERSTATUS:
                    WinHttpClass_ShowServerStatus();
                    break;
                case TaskType.TASK_DOWNLOADOPEN:
                    WinHttpClass_OpenDownloadedFile();
                    break;
            }
        }
        public void WinHttpClass_ShowServerStatus()
        {
            object xmlBody = WinHttpClass.ResponseBody;
            Logic.ShowServerStatus(xmlBody as byte[]);
        }
        public void WinHttpClass_OnMediaThumb()
        {
            object xmlBody = WinHttpClass.ResponseBody;
            Logic.RefreshThumb(Param, xmlBody as byte[]);
        }
        public void WinHttpClass_DownloadPercent(ref Array Data)
        {
            string headers = WinHttpClass.GetAllResponseHeaders();
            string AllLength = WinHttpClass.GetResponseHeader("Content-Length");
            int percent = (Data.Length + DownloadLen)/(Convert.ToInt32(AllLength)/100);

            byte[] ByteData = Data as byte[];
            DownloadFile.Write(ByteData, 0, ByteData.Length);
            DownloadLen += ByteData.Length;
            Logic.DownloadPercent(Param, percent);
        }
        public void WinHttpClass_OnMedia()
        {
            DownloadFile.Close();
            Logic.RefreshMedia(Param);
        }
        public void WinHttpClass_OpenDownloadedFile()
        {
            DownloadFile.Close();
            Logic.OpenDownloadedFile(Param);
        }
        public void WinHttpClass_OnMedias()
        {
            object xmlBody = WinHttpClass.ResponseBody;
            if (xmlBody == null)
            {
                Logic.PrepareFolder(Param);
                Logic.FinishFolder(Param);
                return;
            }
            string XmlText = WinHttpClass.ResponseText;
            String AppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

            AppData += "\\DoCoMedia\\WinHomeServer\\ClientReceive\\";
            AppData += Logic.GetMd5HashPath(Param);
            AppData += ".xml";

            IntPtr XmlData = Marshal.StringToHGlobalUni(XmlText);
            //IntPtr Folder = Marshal.StringToHGlobalUni(Param);

            ServerDataHelper.SetXMLData(xmlBody as byte[]);

            Logic.PrepareFolder(Param);
            int Count = 0;
            ServerDataHelper.GetShareItemCount(ref Count);
            for (int i = 0; i < Count; i++)
            {
                SERVERDATA_MEDIA ShareFolder = new SERVERDATA_MEDIA();
                ServerDataHelper.GetShareItemInfo(i, ref ShareFolder);
                Logic.AddFolderMedia(Param, ShareFolder);
            }
            Logic.FinishFolder(Param);
        }
        public void WinHttpClass_OnRoot()
        {
            object xmlBody = WinHttpClass.ResponseBody;
            if (xmlBody == null)
            {
                Logic.ResetRootData();
                Logic.FinishRootFolder();
                return;
            }
            string XmlText = WinHttpClass.ResponseText;
            //string XmlText = Microsoft.JScript.GlobalObject.decodeURI(strEscaped);

            String AppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            AppData += "\\DoCoMedia\\WinHomeServer\\ClientReceive\\ServerData.xml";
            //StreamWriter writer = new StreamWriter(AppData, false, Encoding.ASCII);
            //writer.Write(XmlText);
            //writer.Close();

            ServerDataHelper.SetXMLData(xmlBody as byte[]);

            Logic.ResetRootData();
            int Count = 0;
            ServerDataHelper.GetShareFolderListCount(ref Count);
            for (int i = 0; i < Count; i++)
            {
                SERVERDATA_SHAREDFOLDER ShareFolder = new SERVERDATA_SHAREDFOLDER();
                ServerDataHelper.GetShareFolderListItem(i, ref ShareFolder);
                Logic.AddRootFolder(ShareFolder);
            }
            Logic.FinishRootFolder();
        }
        public void WinHttpClass_OnError(int ErrorNumber, string ErrorDescription)
        {
            string text = WinHttpClass.StatusText;
            string str = string.Format("The error Number =%d",ErrorNumber);
            string strinfo = ErrorDescription + str;


            MessageBox.Show(strinfo);

        }
        
        public void WinHttpClass_OnLogin()
        {
            object xmlBody = WinHttpClass.ResponseBody;
            if (xmlBody == null)
            {
                Logic.ResetRootData();
                Logic.FinishRootFolder();
                return;
            }
        }
        public void Stop()
        {
            WinHttpClass.Abort();
        }

        public WinHttpRequestClass WinHttpClass;
        public string URL { get; set; }
        public TaskType Task { get; set; }

        public string ServerIP { get; set; }

        public string Param { get; set; }

        public MainPanel Logic;

        public FileStream DownloadFile { get; set; }

        public int DownloadLen { get; set; }

    };
}
